/***************************************************************
*  Copyright (c) 2007 by GroupMe! Team (www.groupme.net)
*  All rights reserved.
*
*  This file is part of the GroupMe! Project. Source code of 
*  this project is closed and redistribution of this code is
*  prohibited. 
*  
*  Contact: http://www.groupme.net
*
*  This copyright notice MUST APPEAR in all copies of the file!
***************************************************************/
package net.groupme.search.publication;

import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import net.groupme.controller.model.PublicationSearchResult;
import net.groupme.controller.model.SearchResult;
import net.groupme.exceptions.search.SearchEngineException;
import net.groupme.model.MODEL_CONSTANTS;
import net.groupme.search.publication.PUBLICATION_ENGINE_VOCABULARY.CiteULikeSearchStrategy;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import de.nava.informa.core.ChannelIF;
import de.nava.informa.core.ItemIF;
import de.nava.informa.impl.basic.ChannelBuilder;
import de.nava.informa.parsers.FeedParser;

/**
 * created on Jul 31, 2007
 * 
 * <p>This engine performs a search on top of <a href="http://www.citeulike.org">http://www.citeulike.org</a>
 * to aggregate publications.</p> 
 * <p>Further publication search engines should be added:</p>
 * <ul>
 * 		<li><a href="http://citeseer.ist.psu.edu/">citeseer</a></li>
 * 		<li><a href="http://www.bibsonomy.org">bibsonomy</a></li>
 * 		<li><a href="http://scholar.google.de/">Google scholar</a></li>
 * 		<li>...</li>
 * </ul>
 * 
 * @author Fabian Abel, <a href="mailto:abel@l3s.de">abel@l3s.de</a>
 * @author last edited by: $Author: fabian $
 * 
 * @version $Revision: 1.1 $ $Date: 2007-08-01 09:57:53 $
 */
public class PublicationSearchEngine {
	
	/** Logger for this class and subclasses */
	protected final Log logger = LogFactory.getLog(getClass());
	
	/**
	 * Performs a standard search at CiteULike and returns publications whose 
	 * title contain the given keywords.
	 * 
	 * @param keywords keywords that should be contained in the title of a publication
	 * @param numberOfResults maximum number of results
	 * @return fitting publications
	 * @throws SearchEngineException thrown if an exception occurs during search...
	 */
	public List<SearchResult> search(String keywords, int numberOfResults) throws SearchEngineException {
		List<SearchResult> results = new ArrayList<SearchResult>();
		String searchURL = PUBLICATION_ENGINE_VOCABULARY.getCiteULikeSearchURL(keywords, CiteULikeSearchStrategy.TITLE);
		logger.info("Search URL: " +searchURL);
		ChannelIF channel = null;
		try {
			URL url =  new URL(searchURL);
			//URLConnection con = url.openConnection(); 
		    //con.setRequestProperty( "User-Agent", "Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0; H010818)" ); 
			channel = FeedParser.parse(new ChannelBuilder(), url);
		} catch (Exception e) {
			throw new SearchEngineException("Failed to parse the search feed", e);
		}
		if(channel == null || channel.getItems().size() == 0){
			return results;
		}
		Set<ItemIF> items = channel.getItems();
		int actualResultCount = 1;
		for (ItemIF item: items) {
			String publicationURL = null;
			if(item.getLink() != null){
				publicationURL = item.getLink().toString();
			}else if(item.getGuid() != null){
				publicationURL = item.getGuid().getLocation();
			}
			PublicationSearchResult publication = new PublicationSearchResult("" + actualResultCount, item.getTitle(), publicationURL,item.getDescription(), MODEL_CONSTANTS.RESOURCE_TYPE_PUBLICATION);
			publication.setBibtexURL(PUBLICATION_ENGINE_VOCABULARY.getBibTexURL(publicationURL));
			results.add(publication);
			if(!(actualResultCount < numberOfResults)){
				return results;
			}
			actualResultCount++;
		}
		return results;
	}

}
